#include <sqlite3.h>
#include <stdio.h>

//这是与函数结合使用的回调函数的函数原型。sqlite3_exec()
int callback(void *, int, char **, char **);

/*
	功能：我们使用 SQL 语句从表中检索所有行。SELECT * FROM CarsCars

	gcc -o select_all select_all.c -lsqlite3
	./select_all
*/


int main(void) {
    
    sqlite3 *db;
    char *err_msg = 0;
    
    int rc = sqlite3_open("test.db", &db);
    
    if (rc != SQLITE_OK) {
        
        fprintf(stderr, "Cannot open database: %s\n", 
                sqlite3_errmsg(db));
        sqlite3_close(db);
        
        return 1;
    }

    //SQL语句，查询 Cars表中 所有数据
    char *sql = "SELECT * FROM Cars";


    //该函数对 SQL 语句进行赋值。
    //对于从计算的 SQL 语句中得出的每个结果行，将调用其回调函数。    

    rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
	/*
		对于sqlite3_exec()函数的参数三：
				 函数指针，   	 回调函数
          		 如果为空，    	 表示没有回调函数
                 如果不为空，则在执行SELECT语句时候会调用回调函数
                 回调函数   主要是处理SELECT查询的结果	
	*/

    if (rc != SQLITE_OK ) {
        
        fprintf(stderr, "Failed to select data\n");
        fprintf(stderr, "SQL error: %s\n", err_msg);

        sqlite3_free(err_msg);
        sqlite3_close(db);
        
        return 1;
    } 
    
    sqlite3_close(db);
    
    return 0;
}

/*
	回调函数的第一个参数是 ;它通常不使用。
	第二个参数是   		结果中的列数。
	第三个参数是			表示行中字段的字符串数组。
	最后一个参数是	   	 	表示列名的字符串数组。sqlite3_exec()

	在函数体中，我们遍历所有列并打印其名称和内容。
*/
int callback(void *NotUsed, int argc, char **argv, 
                    char **azColName) {
    
    NotUsed = 0;
    
    for (int i = 0; i < argc; i++) {

        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    
    printf("\n");
    
    return 0;
}

